<template>
     <div class="yh-form">
          <el-form :label-width="labelWidth" :model="formData" ref="formRef">
               <slot name="paddword"></slot>
               <el-row :class="rowClass">
                    <template v-for="(item, index) in formItems" :key="index">
                         <el-col v-bind="colLayout" v-if="item?.visible">
                              <template v-if="item.slotName">
                                   <slot
                                        :name="item.slotName"
                                        :row="item"
                                        :data="formData"
                                   ></slot>
                              </template>
                              <template v-else>
                                   <el-form-item
                                        :label="item.label"
                                        :rules="item.rules"
                                        :prop="item.field"
                                        :class="labelClass(item)"
                                        :style="itemStyleComputed"
                                   >
                                        <component
                                             :is="formComponent(item.type)"
                                             v-bind="getComponentProps(item)"
                                             v-model="formData[item.field]"
                                        >
                                             <template
                                                  v-if="
                                                       isSelectComponent(
                                                            item.type,
                                                       )
                                                  "
                                             >
                                                  <el-option
                                                       v-for="option in item.options"
                                                       :key="option.value"
                                                       :value="option.value"
                                                       :label="option.label"
                                                  />
                                             </template>
                                        </component>
                                   </el-form-item>
                              </template>
                         </el-col>
                    </template>
                    <el-col v-bind="colLayout">
                         <div class="footer">
                              <slot name="footer"></slot>
                         </div>
                    </el-col>
               </el-row>
          </el-form>
     </div>
</template>

<script lang="ts">
import { defineComponent, PropType, ref, watch, computed } from 'vue'
import type { FormInstance } from 'element-plus'
import { IFormItem } from '../types'
import zhCn from 'element-plus/es/locale/lang/zh-cn'

export default defineComponent({
     props: {
          senior: {
               type: String,
               default: 'null',
          },
          modelValue: {
               type: Object,
          },
          labelWidth: {
               type: String,
               default: '80px',
          },
          formItems: {
               type: Array as PropType<IFormItem[]>,
               default: () => [],
          },
          itemStyle: {
               type: Object,
               default: () => ({ padding: '10px 10px' }),
          },
          itemStyleserin: {
               type: Object,
               default: () => ({ padding: '10px 10px', width: '300px' }),
          },
          nestingiframetype: {
               type: String,
               default: '',
          },
          colLayout: {
               type: Object,
               default: () => ({
                    xl: 6,
                    lg: 8,
                    md: 12,
                    sm: 24,
                    xs: 24,
               }),
          },
     },
     emits: ['update:modelValue', 'modalChange'],
     setup(props, { emit }) {
          const locale = ref(zhCn)
          const formData = ref()
          const formRef = ref<FormInstance>()

          // 计算属性
          const rowClass = computed(() => {
               switch (props.senior) {
                    case 'senior':
                         return 'yh-senior form-class'
                    case 'history':
                         return 'yh-history'
                    default:
                         return 'form-class'
               }
          })

          const itemStyleComputed = computed(() => {
               return props.senior === 'senior' || props.senior === 'history'
                    ? props.itemStyleserin
                    : props.itemStyle
          })

          // 方法
          const labelClass = (item: IFormItem) => {
               return item.label.length > 7
                    ? 'foldLabel form-item'
                    : 'form-item'
          }

          const formComponent = (type: string) => {
               const componentMap: Record<string, string> = {
                    input: 'el-input',
                    password: 'el-input',
                    number: 'el-input',
                    textarea: 'el-input',
                    select: 'el-select',
                    selectdx: 'el-select',
                    cascader: 'el-cascader',
                    datepicker: 'el-date-picker',
                    picker: 'el-date-picker',
                    month: 'el-date-picker',
                    datetime: 'el-date-picker',
                    Switch: 'el-switch',
               }
               return componentMap[type] || 'el-input'
          }

          const isSelectComponent = (type: string) => {
               return ['select', 'selectdx'].includes(type)
          }

          const getComponentProps = (item: IFormItem) => {
               const baseProps = {
                    ...item,
                    disabled: item.disabled,
                    placeholder: item.placeHolder,
                    ...item.otherOption,
               }
               delete baseProps.visible
               switch (item.type) {
                    case 'password':
                         return { ...baseProps, 'show-password': true }
                    case 'number':
                         return { ...baseProps, type: 'number' }
                    case 'textarea':
                         return { ...baseProps, type: 'textarea' }
                    case 'select':
                         return {
                              ...baseProps,
                              style: { width: '100%' },
                              filterable: item.filterable,
                              clearable: item.clearable,
                         }
                    case 'selectdx':
                         return {
                              ...baseProps,
                              multiple: true,
                              'collapse-tags': true,
                              style: { width: '100%' },
                         }
                    case 'cascader':
                         return {
                              ...baseProps,
                              options: item.cascader,
                              props: item.props,
                              'collapse-tags': true,
                              'collapse-tags-tooltip': true,
                         }
                    case 'datepicker':
                         return {
                              ...baseProps,
                              style: { width: '100%' },
                         }
                    case 'picker':
                    case 'month':
                    case 'datetime':
                         return {
                              ...baseProps,
                              style: { width: '100%' },
                              type:
                                   item.type === 'month'
                                        ? 'month'
                                        : item.type === 'datetime'
                                          ? 'datetime'
                                          : undefined,
                         }
                    case 'Switch':
                         return {
                              style: {
                                   '--el-switch-on-color': '#13ce66',
                                   '--el-switch-off-color': '#ff4949',
                              },
                         }
                    default:
                         return baseProps
               }
          }

          // 监听
          watch(
               () => props,
               (newValue) => {
                    formData.value = newValue.modelValue
                    emit('modalChange', newValue.modelValue)
                    emit('update:modelValue', newValue.modelValue)
               },
               {
                    deep: true,
                    immediate: true,
               },
          )

          return {
               formData,
               formRef,
               locale,
               rowClass,
               itemStyleComputed,
               labelClass,
               formComponent,
               isSelectComponent,
               getComponentProps,
          }
     },
})
</script>

<style scoped lang="scss">
.yh-form {
     padding: 0;

     .form-class {
          width: 99%;

          .footer {
               padding: 10px;
          }
     }

     .yh-history {
          width: 100%;

          .footer {
               padding: 10px;
          }
     }

     .yh-senior {
          display: flex;
          flex-direction: column;
     }

     .foldLabel {
          // 折叠标签的样式
     }
}
</style>
